/*  
 *  Nanjing JIYU Technology Co.,Ltd All rights reserved.
 *  Copyright (C) 2022 
 *  ==============================================================
 * 
 *  system.c 
 *    RCC与延时功能配置
 *
 *  --------------------------------------------------------------
 *  
 */

#include "system.h"


static void system_rcc_config(u32 PLL)
{
  HAL_StatusTypeDef ret = HAL_OK;
  RCC_OscInitTypeDef RCC_OscInitStructure;
  RCC_ClkInitTypeDef RCC_ClkInitStructure;

  RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSE;      /* 时钟源为HSE         */
  RCC_OscInitStructure.HSEState = RCC_HSE_ON;                        /* 打开HSE             */
  RCC_OscInitStructure.HSEPredivValue = RCC_HSE_PREDIV_DIV1;         /* HSE预分频           */
  RCC_OscInitStructure.PLL.PLLState = RCC_PLL_ON;                    /* 打开PLL             */
  RCC_OscInitStructure.PLL.PLLSource = RCC_PLLSOURCE_HSE;            /* PLL时钟源选择HSE    */
  RCC_OscInitStructure.PLL.PLLMUL = PLL;                             /* 主PLL倍频因子       */
  ret = HAL_RCC_OscConfig(&RCC_OscInitStructure);                    /* 初始化              */

  if (ret != HAL_OK)
    while (1);

  RCC_ClkInitStructure.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
                                    RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStructure.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;        /* 设置系统时钟时钟源为PLL            */
  RCC_ClkInitStructure.AHBCLKDivider = RCC_SYSCLK_DIV1;               /* AHB分频系数为1                     */
  RCC_ClkInitStructure.APB1CLKDivider = RCC_HCLK_DIV2;                /* APB1分频系数为2                    */
  RCC_ClkInitStructure.APB2CLKDivider = RCC_HCLK_DIV1;                /* APB2分频系数为1                    */
  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStructure, FLASH_LATENCY_2);  /* 设置FLASH延时周期2WS，3个CPU周期   */

  if (ret != HAL_OK)
    while (1);
}


static u32 fac_us = 0;              //us延时倍乘数

static void system_delay_init(u8 SYSCLK)
{
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
  fac_us = SYSCLK;
}

void system_clock_init(void)
{
  system_rcc_config(RCC_PLL_MUL9);
  system_delay_init(72);
}


/* 最大延时190887435 */
void delay_us(u32 us)
{
  u32 ticks;
  u32 told, tnow, tcnt = 0;
  u32 reload = SysTick->LOAD;
  ticks = us * fac_us;
  told = SysTick->VAL;
  while (1)
  {
    tnow = SysTick->VAL;
    if (tnow != told)
    {
      if (tnow < told)
        tcnt += told - tnow;
      else
        tcnt += reload - tnow + told;
      told = tnow;
      if (tcnt >= ticks)
        break;
    }
  }
}


void delay_ms(u16 ms)
{
  u32 i;
  for (i = 0; i < ms; i++)
    delay_us(1000);
}



